Удалить аккаунт могут в крайних случаях за нарушения правил, например, клоноразведение в особо крупных масштабах. Вернуться после этого в большинстве случаев нельзя.
Удаление аккаунтов "по просьбе" не осуществляется.
система урона + ледяные стрелы = при получении урона, идет проверка на бафф, удаляешь бафф и, либо кастуешь даммиком способность кислотная бомба или духовное пламя с отриц. значением минус в том что бафф будет висеть как положительный. Либо под таймером даешь даешь способность повышения защиты с отриц. значением.
Учитывая что 21 век, систему урона найти и поставить, не составит труда.
Dota_2015, с какого перепугу ATTACK_TYPE_MAGIC урон от заклинаний? у заклинаний тип атаки ATTACK_TYPE_NORMAL, а у тебя это магическая атака волшебниц да прочей шушеры из кампании, наносит 75% урона про героям и доп урон по тяжёлой броне, маг. резистами не режится ибо физический урон от атаки.
У всех заклинаний, да блин даже у долбаных мин гоблина - тип атаки ATTACK_TYPE_NORMAL.
void - это nothing то есть ничего не возвращает функция, а саму функции называют doTheThing, а unit u - аргументы функции, мануалы про cjass почитай (хотя я тоже соглашусь, что написано очень плохо в мануалах. Нужно попробовать немного самим пописать коды)
можно представить как (если хорошо понимаешь jass)
function doTheThing takes unit u returns nothing
... //что-то делаешь с юнитом u (берем аргумент функции - unit u)
endfunction
GetMyUnit - такой не существует, видимо Док имеет в виду подставить свою переменную
пример
например составил пример функции - определить уровень абилы юнита. Функция называется LV, u - юнит, id - целое число, равкод абилы. Возвращает целое число (уровень абилы).
function LV takes unit u, integer id returns integer
return GetUnitAbilityLevel(u, id)
endfunction
'A000' - равкод абилы
local integer lv = LV(GetTriggerUnit(), 'A000') //узнаем уровень героя
название KillUnit не совсем подходит
я бы назвал killUnitFromUnit или просто killFromUnit Пушистый, а можно проще
define KillUnit(a) = KillUnit2(a)
по поводу правил
название должны соответствовать выполняемой функции
например если логическая переменная хранит жив юнит или нет то называться она должна isAlive или как то так
+ различные правила написания для различных языков
например в java первое слово в названии функции/переменной пишется с маленькой буквы а остальные с большой, а в названиях классов все слова с большой
в jass официальных соглашений нету но близы писали в функциях каждое слово с большой а константы большими буквами разделяя слова _
local real x = GetRandomReal(GetRectMinX(GetPlayableMapRect()), GetRectMaxX(GetPlayableMapRect()))
local real y = GetRandomReal(GetRectMinY(GetPlayableMapRect()), GetRectMaxY(GetPlayableMapRect()))
...
(действия с координатами)
...
Любые действия с локейшном можно переделать под координаты, если не используется z-координата, как сказано выше. Но z-координату используют не только лишь все, мало кто может это делать.
И обнулять ничего не придётся, так как действительное число не утекает.
А теперь скажи: Ты добавлял модели обычным методом или подключаемым модулем?
Если первое, то да - будут отображаться. Если же второе, то надо скинуть модуль/архив
Nelloy, будет но для этого данные нужно синхронизировать, для ваших сейв\лоадов есть давно проверенная система, которая не требует мемхака - Data Manager, не надо никакого мемхака. Все понятно и просто, вот неужели нельзя изучить всю мат часть по сейвам прежде чем пороть горячку?
Если по игроку то массив переменных по игроку, если прям каждого конкретного героя каждого игрока - то через custom value или прочий регистратор юнитов.
Эмм что за ерунда, сократил код, убрав всё лишнее, но утечки все равно остаются, по 1.5 - 2 хэндла за каждое нанесение урона (тип хэндла не знаю как посмотреть). Когда триггер отключаешь, то всё нормально.
Сокращенный код
function SDMSCreateTextTag takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit s=GetEventDamageSource()
local integer i=GetConvertedPlayerId(GetOwningPlayer(u))
local texttag tt=CreateTextTag()
local real dmg=GetEventDamage()
if ( dmg > 1.00 ) and ( dmg < 9999.00 ) then
if GetPlayerId(GetOwningPlayer(u))==12 then
call SetTextTagText(tt, "|cff9db9eb-"+I2S(R2I(dmg))+"|r", 0.023)
else
call SetTextTagText(tt, "|cffffa500-"+I2S(R2I(dmg))+"|r", 0.023)
endif
call SetTextTagPosUnit(tt, u, 0)
call SetTextTagColor(tt, 255, 255, 255, 255)
call SetTextTagVelocity(tt, 0.05325*Cos(90 * bj_DEGTORAD), 0.05325*Sin(90 * bj_DEGTORAD))
call SetTextTagPermanent(tt, false)
call SetTextTagLifespan(tt, 1.0)
call SetTextTagFadepoint(tt, 0.0)
endif
call PolledWait(2.0)
call DestroyTextTag(tt)
set u=null
set s=null
set i=0
set dmg=0
set tt=null
endfunction
function SDMSTriggerRegisterUnitDamaged takes nothing returns nothing
call TriggerRegisterUnitEvent(udg_SDMStrigger,GetEnteringUnit(),EVENT_UNIT_DAMAGED)
endfunction
function theSDMSTriggerActions takes nothing returns nothing
local trigger UnitEnter=CreateTrigger()
call TriggerRegisterEnterRectSimple(UnitEnter, gg_rct_Arena)
call TriggerAddAction(UnitEnter,function SDMSTriggerRegisterUnitDamaged)
set UnitEnter=null
endfunction
function InitTrig_the_SDMS_Trigger takes nothing returns nothing
local trigger tr=CreateTrigger()
set udg_SDMStrigger=CreateTrigger()//Тут также меняется название глобальной переменной типа триггер.
call TriggerAddAction(udg_SDMStrigger,function SDMSCreateTextTag)
call TriggerRegisterTimerEventSingle(tr,0.0)
call TriggerAddAction(tr,function theSDMSTriggerActions)
set tr=null
endfunction
Wait вызывает утечки ((
Пришлось делать через таймер
событие
generic unit event - боевая еденица зашла в область boss gen
Условие
Unit Type companishon - triggering unit не = герой
действие
Боевая еденица - move triggering unit to center of nearboss gen
Text message to груупа игров(owner of triggering unit) сюда может войти только герой!
Sergey105, проблема в способе хранения а не в вджасс
цикл бегает от 1 до count включительно
первый объект будет в 1 ячейке
второй во 2
третий в третьей
count равен 3
раз время везде 6 секунд то первой освободиться первая ячейка
count станет равен 2
и цикл будет обрабатывать ячейки 1(пустая) и 2
но объект в 3 ячейке всё ещё остался так как время для него не закончилось
а так как мы его не удалили а просто потеряли то и эффект и экземпляр структуры остаются
и того утечка памяти
вот статья которую можно юзать как пример
В помощь тебе библиотеки(library) и базы данных.
Либы — для обращения по виду library_name.functionName(arguments)
Базы данных — для выделения юниту своих переменных.
С БД может быть момент не совсем понятным, поэтому скидываю пример:
Эта порнография разработана для личного пользования
У меня в коде есть иллюзия использования вжасса. Либа просто для доп табуляции и невостребованых манипуляций на случай импорта. При создании юнита ему присваивается ряд переменных, а номер этих переменных, относящихся к этому юниту, записывается в его(юнита) UnitUserData
library UnitDataBase
globals
constant integer UnitDBSize = 512
constant integer UnitDBHeroesStart = 0
constant integer UnitDBHeroesUnder = 49
constant integer UnitDBUnitsStart = 50//Includes illusions of heroes. Or Should include them at least :P
constant integer UnitDBUnitsUnder = 319
constant integer UnitDBSummonsStart = 320
constant integer UnitDBSummonsUnder = 511
integer UnitDBNextHero = 0
integer UnitDBNextUnit = 50
integer UnitDBNextSummon = 320
unit array UnitDBUnit[UnitDBSize]
real array UnitDBCurrentAnimationSpeed[UnitDBSize]
unit array UnitDBForceAttackTarget[UnitDBSize]
integer array UnitDBAffectedByStuns[UnitDBSize]
real array UnitDBMagicResistance[UnitDBSize]
real array UnitDBPhysResistance[UnitDBSize]
real array UnitDBCurrentArmor[UnitDBSize]//This armor does not include agility bonuses. Not used yet :>
real array UnitDBWhiteMovementSpeed[UnitDBSize]
real array UnitDBCurrentCustomSlow[UnitDBSize]
real array UnitDBMagicDamageAmplifier[UnitDBSize]
real array UnitDBPhysDamageAmplifier[UnitDBSize]
real array UnitDBAdditionalHealth[UnitDBSize]//AKA Shield. Healed whenever unit takes damage.
constant real GravityAcceleration = 14.//Azeroth, bitch!
real array UnitDBFlyingHeight[UnitDBSize]//Not used yet
real array UnitDBFallingSpeed[UnitDBSize]
integer array UnitDBItemUseVariable[UnitDBUnitsStart]//just don't ask
item array UnitDBLastUsedItem[UnitDBUnitsStart]
real array UnitDBCastPointX[UnitDBUnitsStart]
real array UnitDBCastPointY[UnitDBUnitsStart]
integer UnitDBPreviousHero//Used for exitwhen event. Its next minus two.
unit array UnitDBHeroHPBar[UnitDBUnitsStart]
unit array UnitDBHeroMPBar[UnitDBUnitsStart]
unit array UnitDBHeroSPBar[UnitDBUnitsStart]
endglobals
//Больно жирные для инлайна
function UnitDBFindNextFreeVariable takes integer i returns integer
local unit u
loop
set u = UnitDBUnit[i]
exitwhen u == null or GetUnitTypeId( u ) < 1
set i = i + 1
endloop
set u = null
return i
endfunction
function UnitDBAddHero takes unit u, real mdef, real armor returns nothing
local integer i = UnitDBNextHero
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call UnitMakeAbilityPermanent( u, true, 'A00B' )
set UnitDBUnit[i] = u
call SetUnitUserData( u, i )
call GroupAddUnit( UnitsInPlayableArea, u )
set UnitDBItemUseVariable[i] = 0
set UnitDBCurrentAnimationSpeed[i] = 0.
set UnitDBAffectedByStuns[i] = 0
set UnitDBMagicResistance[i] = mdef
set UnitDBCurrentArmor[i] = armor
set UnitDBWhiteMovementSpeed[i] = GetUnitDefaultMoveSpeed( u )
set UnitDBCurrentCustomSlow[i] = 1.
set UnitDBMagicDamageAmplifier[i] = 1.
set UnitDBPhysDamageAmplifier[i] = 1.
set UnitDBFlyingHeight[i] = 0.//Doesn't include point height.
set UnitDBAdditionalHealth[i] = 0.
/*if ( i == UnitDBHeroesUnder ) then
call BJDebugMsg("|c00ff6060Hero limit reached! More heroes can be created, but things can go wild.")
endif*/
set UnitDBNextHero = i + 1
set UnitDBPreviousHero = i - 1
set UnitDBHeroHPBar[i] = CreateUnit(BossPlayer1, 'hmil', x, y, 0. )
call SetUnitAnimationByIndex( UnitDBHeroHPBar[i], 100 )
set UnitDBHeroMPBar[i] = CreateUnit( BossPlayer1, 'hrtt', x, y, 0. )
call SetUnitAnimationByIndex( UnitDBHeroMPBar[i], 100 )
set UnitDBHeroSPBar[i] = CreateUnit( BossPlayer1, 'hwt2', x, y, 0. )
call SetUnitAnimationByIndex( UnitDBHeroSPBar[i], 0 )
set u = null
return
endfunction
function UnitDBAddUnit takes unit createdUnit, real mdef, real armor returns nothing
local integer i = UnitDBNextUnit
local unit u = UnitDBUnit[i]
if ( u == null ) then
set i = UnitDBFindNextFreeVariable( UnitDBSummonsStart )
endif
set UnitDBUnit[i] = createdUnit
call SetUnitUserData( createdUnit, i )
call GroupAddUnit( UnitsInPlayableArea, createdUnit )
set UnitDBCurrentAnimationSpeed[i] = 0.
set UnitDBAffectedByStuns[i] = 0
set UnitDBMagicResistance[i] = mdef
set UnitDBCurrentArmor[i] = armor
set UnitDBWhiteMovementSpeed[i] = GetUnitDefaultMoveSpeed( createdUnit )
set UnitDBCurrentCustomSlow[i] = 1.
set UnitDBMagicDamageAmplifier[i] = 1.
set UnitDBPhysDamageAmplifier[i] = 1.
set UnitDBFlyingHeight[i] = 0.
set UnitDBAdditionalHealth[i] = 0.
if ( i < UnitDBSummonsUnder) then
set UnitDBNextSummon = i + 1
else
set UnitDBNextSummon = UnitDBSummonsStart
endif
set u = null
set createdUnit = null
return
endfunction
function UnitDBAddSummon takes unit summonedUnit, real mdef, real armor returns nothing
local integer i = UnitDBNextSummon
local unit u = UnitDBUnit[i]
if ( u == null ) then
set i = UnitDBFindNextFreeVariable( UnitDBSummonsStart )
endif
set UnitDBUnit[i] = summonedUnit
call SetUnitUserData( summonedUnit, i )
call GroupAddUnit( UnitsInPlayableArea, summonedUnit )
set UnitDBCurrentAnimationSpeed[i] = 0.
set UnitDBAffectedByStuns[i] = 0
set UnitDBMagicResistance[i] = mdef
set UnitDBCurrentArmor[i] = armor
set UnitDBWhiteMovementSpeed[i] = GetUnitDefaultMoveSpeed( summonedUnit )
set UnitDBCurrentCustomSlow[i] = 1.
set UnitDBMagicDamageAmplifier[i] = 1.
set UnitDBPhysDamageAmplifier[i] = 1.
set UnitDBFlyingHeight[i] = 0.
set UnitDBAdditionalHealth[i] = 0.
if ( i < UnitDBSummonsUnder) then
set UnitDBNextSummon = i + 1
else
set UnitDBNextSummon = UnitDBSummonsStart
endif
set u = null
set summonedUnit = null
return
endfunction
//Система маг резиста была изменена на дефолтную, была введена аналогичная ей система физ урона.
//Необходимо протестить эти системы на низких значениях. (могучий float и его точность). В нынешних условиях низкие значения не достигаются. На тест положен болт. Есть нерешенные проблемы с точностью(при восстановлении, опять же, резисты съезжают). Необходимо учитывать при вычислениях лишь первые три цифры после запятой, например.
#define UnitDBIncreaseUnitMagicResistance( amount, userData ) = {
set UnitDBMagicResistance[userData] = UnitDBMagicResistance[userData] * amount
}
#define UnitDBDecreaseUnitMagicResistance( amount, userData ) = {
set UnitDBMagicResistance[userData] = UnitDBMagicResistance[userData] / amount
if ( UnitDBMagicResistance[userData] > 0.99997 and UnitDBMagicResistance[userData] < 1.00003 ) then
set UnitDBMagicResistance[userData] = 1.
endif
}
#define UnitDBIncreaseUnitPhysResistance( amount, userData ) = {
set UnitDBPhysResistance[userData] = UnitDBPhysResistance[userData] * amount
}
#define UnitDBDecreaseUnitPhysResistance( amount, userData ) = {
set UnitDBPhysResistance[userData] = UnitDBPhysResistance[userData] / amount
if ( UnitDBPhysResistance[userData] > 0.99997 and UnitDBPhysResistance[userData] < 1.00003 ) then
set UnitDBPhysResistance[userData] = 1.
endif
}
#define UnitDBReplaceUnitMagicResistance( before, after, userData ) = {
set UnitDBMagicResistance[userData] = UnitDBMagicResistance[userData] / before * after
}
#define UnitDBReplaceUnitPhysResistance( before, after, userData ) = {
set UnitDBPhysResistance[userData] = UnitDBPhysResistance[userData] / before * after
}
#define UnitDBIncreaseUnitMagicDamageAmplifier( amount, userData ) = {
set UnitDBMagicDamageAmplifier[userData] = UnitDBMagicDamageAmplifier[userData] + amount
}
#define UnitDBDecreaseUnitMagicDamageAmplifier( amount, userData ) = {
set UnitDBMagicDamageAmplifier[userData] = UnitDBMagicDamageAmplifier[userData] - amount
if ( UnitDBMagicDamageAmplifier[userData] > 0.99997 and UnitDBMagicDamageAmplifier[userData] < 1.00003 ) then
set UnitDBMagicDamageAmplifier[userData] = 1.
endif
}
#define UnitDBIncreaseUnitPhysDamageAmplifier( amount, userData ) = {
set UnitDBPhysDamageAmplifier[userData] = UnitDBPhysDamageAmplifier[userData] + amount
}
#define UnitDBDecreaseUnitPhysDamageAmplifier( amount, userData ) = {
set UnitDBPhysDamageAmplifier[userData] = UnitDBPhysDamageAmplifier[userData] - amount
if ( UnitDBPhysDamageAmplifier[userData] > 0.99997 and UnitDBPhysDamageAmplifier[userData] < 1.00003 ) then
set UnitDBPhysDamageAmplifier[userData] = 1.
endif
}
#define UnitDBIncreaseUnitShield( amount, userData ) = {
set UnitDBAdditionalHealth[userData] = UnitDBAdditionalHealth[userData] + amount
//redraw
}
#define UnitDBDecreaseUnitShield( amount, userData ) = {
set UnitDBAdditionalHealth[userData] = UnitDBAdditionalHealth[userData] - amount
if ( UnitDBAdditionalHealth[userData] < 0. ) then//Perhaps should be typed manually on every use. No need of that atm.
set UnitDBAdditionalHealth[userData] = 0.
endif
//redraw
}
function UnitDBAddUnitsCreatedOnInit takes nothing returns nothing
local unit u = GetEnumUnit()
if ( not IsUnitType( u, UNIT_TYPE_HERO ) ) then
call UnitDBAddUnit( u, 1., 0. )//!!! whatever
endif
set u = null
return
endfunction
endlibrary
это объявление глобальных переменных, так используются и в обычном редакторе. только, если нужно создать свои, мы заходим в редактор переменных и создаем (хоть мы не видим код, а редактор переменных автоматом тип и название внесет в эту конструкцию, что ты выше написал). А в vjass и cjass мы можем объявлять свои переменные в любом участке кода, все что нужно, так это написать так это тип переменной и название переменной на английском.
пример
globals
тип и название переменной
unit U //пример
endglobals
глобальная переменная в отличии от локальной работает везде: в триггере, коде и др. Для всех игроков вроде общие. Не слышал об этом. Похоже, что, да, придется создавать массивы, чтобы у каждого был свой индекс массива.
чтобы создать массив пишут array
unit array U
для новичков
но нужно понимать, что все эти vjass и cjass - это для удобства, компилятор переведет его в обычный jass: все объявленные переменные в разных кусках перенесет наверх при компиляции, вон та же библиотека добавляет в main (главная функция карты) нужные функции, у структур наблюдаются изменения в имени переменных (добавляются в названии переменных и функции приставки от имени структуры и др) и прочее. Если новичок, бери прочитай мануал, потом что-то не понятно (библиотеки, структуры и др), бери пустую карту, напиши код, сохрани и компилируй код, потом архиватором вытащи j-файл, и в текстовике посмотри, сравни. Единственное что не привычно и сложно - синтаксис, ведь не знаешь, какими правилами и сочетаниями слов использовать, к примеру call можно не писать, вместо if endif скобочки и др.
Во внутреннем представлении (читай: "после отработки препроцессора JassHelper") любая структура есть набор массивов с индексом, по которому лежат данные именно этой структуры во всех связанных массивах. По факту, передавая структуру в качестве аргумента функции, ты передаёшь только её id из массива.
По поводу вопроса: полного перевода vJass мануала на русский язык не существует в природе, так что вот ссылка на английский: www.wc3c.net/vexorian/jasshelpermanual.html Крайне рекомендую пользоваться не базовым синтаксисом, а C-подобным, который обеспечивает "AdicHelper" aka cJass (ссылка на русскую версию мануала), это позволит в будущем гораздо проще перейти к программированию на полноценных языках.
nvc123, тогда получается boolexpr не утечна?
его можно создать где угодно)
и использовать как фрог
Лол, обьясняю еще раз
Condition( function SomeFunc ) и Filter( function SomeFunc ) возвращают Boolexpr, он кешируется, и не утекает
Но в триггере еще есть TriggerAddCondition( trigger, boolexpr ) который возвращает triggercondition - который какраз и утекает, это хендл который висит в памяти и требует удаления... туда же triggeraction .
Поэтому там где используются локальные триггеры которые будут удалены нужно удалять и triggeraction и triggercondition а для этого их нужно куда то сохранить, много городушек и лишних действий, посему там где можно не юзать триггеры лучше их не юзать.
bazeba, чтобы мазохисты могли убирать часть утечек и таким образом и дальше заниматься мазохизмом
там ещё точка утекает
Position of () создаёт точку которая утекает
скрин скинул выше, но там ошибка. И если раскрыть, то обнаруживается еще одна утечка: на гуи Point(0,0), а на jass эта команда называется по-другому Location(0,0), эта функция создает точку
раскрыть
попробуй раскрутить, и использовать эту
native CreateItem takes integer itemid, real x, real y returns item
через CS: call CreateItem( id, GetUnitX(u), GetUnitY(u))
где id - ид-номер типа предмета, u - юнит. Ввести тип предмета, и юнита нужно.
можно еще запомнить как-то, чтобы к предмету как-то обращаться
через CS: set it = CreateItem( id, GetUnitX(u), GetUnitY(u))
где it - переменная предмета. Объявить переменную и обращаться
Ige, да о чем вы говорите. ИМХО, самое оптимальное предложение содержится в 3 комментарии.
И еще тут много лишних функций. Да и просто первый признак jass - отсутствие бж за исключением дебага( хоть мои слова кажется трепом и выпендрежем, но без чистого скрипта на нативах.... )
глобальный массив не нужен. сохраняй группу в хэш-таблицу на хэндл героя, потом загружай ее когда надо. у каждого героя будет своя группа
вот пример, молот бурь съедает юнита а удар грома ставит всех юнитов обратно
Проблема возникает также при переносе вот этого вот в инициализацию триггера тест.
Но при этом если вместо строки вроде "12345" использовать, например, GetAbilityName('Aloc') - то все работает.
Это какой-то баг со строками?
Еще у меня почему-то происходит фантомный клик по центру карты в начале игры
Вобщем не стоит юзать имена функций напрямую в экзекуте и вообще таймеры лучше
Wyett, ты можешь добавлять подобные этим:
function ... takes ... returns ...
Код
endfunction
Резака купить можно, но это будет абсолютно не похоже на покупку дирижабля.
Я сам разобрался с проблемой. Конечно тут две новые появились, но на них забью уже:
ИИ не нравился герой, из-за него вообще никто не нанимался.
ИИ посчитал, что улучшив главное здание, он лишается главного здания, а значит нужно его снова строить. То есть, например, улучшив ратушу до крепости, он считает, что ратуши больше нет и необходимо построить ещё одну. Потом он крепость улучшит до замка, посчитает, что разрушили крепость, улучшит до крепости ратушу№2, снова потеряет ратушу и построит уже третью.
Nyanta, для начала дебаг сделать как написано в статье
Сделал. Триггер работает как нужно. При входе всегда пишет "Вход!", при выходе - "Выход!". Порядок текста не меняется.
В общем, проблема, почему-то, была в названии анимации. Открыл модель через MdlVis и назвал анимации "родными" словами Stand, Walk, Death. Стало работать как надо.
Спасибо Rare за Rare:
ставь скорость анимации на 0%
И nvc123 за то, что натолкнул на мысль этим) nvc123:
Тег - это добавление к названию анимации. Он пишется через пробел и триггерно добавить можно только определённые теги.
Ты пытаешься добавить полное имя анимации как тег.
Тебе следует переименовать анимацию attack 2 в мдлвизе например в attack first.
Тогда, при подбирании меча добавляй тег "first"
UniverseRuler, в доте 6-6 использованы игроки 13 и 14
тебе нужно просто сохранять приказ отданный триггерно(ты ведь ими будешь юнитами управлять)
и восстанавливать его при получение приказа для игрока
для этого нужна буленовская переменная для определения триггерный это приказ или нет
и структура/хэш/юзердата для сохранения приказа UniverseRuler:
еще остались асы картостроения, но а сейчас начинаю думать, что их все таки нету
если ас картостроения это человек который воплощает все ваши фантазии в жизнь то тут таких нету и не было
ещё можно создавать всех юнитов за 1 резервного игрока
а автоатаку делать триггерно
этот вариант самый лучший но то просто не сможешь его сделать
ибо нужны джасс+алгоритмы+структуры/хэш
а ты судя по всему ничего из этого не знаешь
не правильно
ты обнулил переменную а потом удалил точку которая в переменной
а так как переменная пустая то ты ничего не удалил
и локалку плохо юзаеш
лучше
local location l=GetUnitLoc(GetTriggerUnit())
так сразу занесёшь в неё позицию юнита который вошёл в область
короче удели хотяб пол часа на это, это , это и вот это
в чем редактор вкв3 отличается от редактора ск2 - к сожалению, в вк3-шном эдиторе не удастся отловить все данные.
если ты скажешь, что конкретно делает твой спелл, тебе могут подсказать более легкий вариант исполнения
насчет спецэффектов - утечка решается просто
создаешь точку, если спец на земле. если спец на юните, точка не требуется.
собсно воспроизводишь спец
и сразу его удаляешь. спец удалится тогда, когда доиграет до конца его анимация
кастом скриптом удаляешь точку, если 1 часть 1 пункта актуальна
leha3, если ты будешь заносить всех созданных юнитов в группу, то тебе нужен "отряд". Но можно и без переменной, просто пикаешь юнитов игрока или в области и считаешь.
Чем не устраивает способность "Дух (видимый)"? Обладатель абилки будет пытаться обходить препятствия, но он сам при расчете карты путей учитывается не будет. Если, конечно, я ничего не путаю.
Проблема возникает также при переносе вот этого вот в инициализацию триггера тест.
Но при этом если вместо строки вроде "12345" использовать, например, GetAbilityName('Aloc') - то все работает.
Это какой-то баг со строками?
Еще у меня почему-то происходит фантомный клик по центру карты в начале игры
Вобщем не стоит юзать имена функций напрямую в экзекуте и вообще таймеры лучше
Объясню, почему я удалил код: после проведённого за кодом времени, я понял, что сильно погорячился, задав такой глупый вопрос. Стоило отдохнуть, проветрить голову, и решение нашлось. Тем, кто столкнулся с хоть самую малость, но похожей проблемой, дам совет: всегда проверяйте соответствия заклинаний, написанных в коде jass (CTRL + D, если кто не знает, как узнать id заклинания) и ,конечно, сам синтаксис. Также посоветую не утраивать "свалку" в коде, как это сделал я. В общем, если кому интересно, как я решил проблему, пишите - расскажу или даже помогу если у вас она схожая.(Всё дело во внимательности)...
Сброшу код триггера таким, каким я его хотел видеть изначально:
function MU_Check_lvl_four takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 4 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_three takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 3 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_two takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 2 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_one takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 1 ) ) then
return false
endif
return true
endfunction
function MU_Second_Conditions takes nothing returns boolean
if ( not ( UnitHasBuffBJ(GetEventDamageSource(), 'B008') == true ) ) then
return false
endif
if ( not ( GetEventDamageSource() == udg_Akame_Killer ) ) then
return false
endif
return true
endfunction
function MU_Start_Conditions takes nothing returns boolean
if ( not ( UnitHasBuffBJ(GetAttacker(), 'B008') == true ) ) then
return false
endif
if ( not ( GetAttacker() == udg_Akame_Killer ) ) then
return false
endif
return true
endfunction
function Trig_MU_Conditions takes nothing returns boolean
if ( not MU_Start_Conditions() ) then
return false
endif
return true
endfunction
function MU_Venum_Check takes nothing returns boolean
if ( not ( udg_MU_Venum_counter == 2 ) ) then
return false
endif
return true
endfunction
function MU_del takes nothing returns nothing
if ( MU_Check_lvl_one() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00X', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00X', GetEventDamageSource() )
else
if ( MU_Check_lvl_two() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00U', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00U', GetEventDamageSource() )
else
if ( MU_Check_lvl_three() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00Y', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00Y', GetEventDamageSource() )
else
if ( MU_Check_lvl_four() ) then
call SetPlayerAbilityAvailableBJ( true, 'A013', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A013', GetEventDamageSource() )
else
call DoNothing( )
endif
endif
endif
endif
endfunction
function Trig_MU_Actions takes nothing returns nothing
call DestroyTrigger(udg_MU_trig)
set udg_MU_Venum_counter = GetRandomInt(1, 5)
set udg_MU_TG = GetAttackedUnitBJ()
if ( MU_Venum_Check() ) then
if ( MU_Check_lvl_one() ) then
call UnitAddAbilityBJ( 'A00X', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00X', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_two() ) then
call UnitAddAbilityBJ( 'A00U', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00U', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_three() ) then
call UnitAddAbilityBJ( 'A00Y', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00Y', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_four() ) then
call UnitAddAbilityBJ( 'A013', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A013', GetOwningPlayer(udg_Akame_Killer) )
else
call DoNothing( )
endif
endif
endif
endif
set udg_MU_trig = CreateTrigger()
call TriggerRegisterUnitEvent( udg_MU_trig, udg_MU_TG, EVENT_UNIT_DAMAGED )
call TriggerAddCondition( udg_MU_trig, Condition( function MU_Second_Conditions ) )
call TriggerAddAction( udg_MU_trig, function MU_del )
else
call DoNothing( )
endif
endfunction
//===========================================================================
function InitTrig_MU takes nothing returns nothing
set gg_trg_MU = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_MU, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_MU, Condition( function Trig_MU_Conditions ) )
call TriggerAddAction( gg_trg_MU, function Trig_MU_Actions )
endfunction
Суть триггера:
Имеется способность с четырьмя уровнями. На каждом уровне урон способности разный, а шанс срабатывания всегда 25%. При атаке герой, имеющий такую способность имеет шанс (25%) на отравление противника.
Переменная udg_Akame_killer равносильна GetEventDamageSource()
P.S. Возможно кому-то даже пригодится этот код... Сделан полнейшим неумехой в плане jass, так что не судите строго!
в триггере с событием инициализация
если триггерная область == null (нету области)
пробегаем циклом по массиву областей
триггер - добавить событие этому триггеру (Юнит входит в область (Rect[А]))
иначе
делаем то что надо делать при входе в 1 из 50 областей
отменять постройку юнита если технология уже ап
либо как сразу говорили через ап здания
где каждому твоему зданию будет соответствовать такое же здание но с дополнительным слотом
с продажей юнита открываешь доту и смотришь как там сделан спелл передать предметы у куры
он сделан как раз через продажу юнита
иначе никак
если не нравится пожалуйся богу об этом
или близардам
пусть выпустят новый патч специально для тебя
Sacar777, выведи после MultiboardGetItem(udg_JC_Board, i-1, 1)
на экран следующий текст
I2S(GetHandleId(q1))
I2S(GetHandleId(q2))
если q2 по каким то причинам не создаётся то это скажет об этом
стоп
а какой у тебя размер столбца стоит?
мб просто ячейка q1 перекрывает собой ячейку q2
и размер 10 это очень много
ведь в отличие от гуи тут размер в сотых указывается
то есть если в гуи размер 10 то тут должен быть 0.1
поставь в MultiboardSetItemWidth(q1, 10.00)
вместо 10.00 0.1 и проверь
если 0.1 не сработает то поставь 0.02
если и это не сработает то отпиши сюда
я тогда раскапаю свой старый мультибоард и сравню с твоим
Это события с опткодом, больше меньше или равно значению в какой то переменной, эти недособытия кривые и работают не везде, порой тупо не срабатывают, я долго возился с событием игровое время равно ... чтобы отследить ночь и день, в сингле это работало в муи были постоянные баги, событие тупо не срабатывало в итоге сделал периодическим таймером.
Мда. Жасс такой жасс.
Как оказалось если пытатся отобразить уже отображенный МБ - варик его скроет... Отсюда и проблемы пошли.
Решение: Сначала все скрываем, а потом локально отображаем и никак иначе. У меня косяк был в том, что в периодике мб показывался локально, и периодик срабатывал раньше отображения.
Tand, под кодировкой я имею в виду кодировку. Есть такая штука, определяет какими комбинациями нулей и едениц в бинарном виде кодируется каждый символ. Если при сохранении использована не та кодировка, которую понимает игра, то игра, соответственно, неможет сопоставить нулям и еденицам из файла конкретные символы, а значит ничего не показывает или показывает совсем не то, что было написано изначально.
Скачай Notepad++ -встроенные в винду средства годятся разве что заметки о жизни офисного планктона писать.
Просто в 1 триг добавь все события Игрок 1 2 3 ввёл пустая строка как подстрока.
Сделал ты правильно, вот только группа игроков вызывает утечку. Если хочешь больше оптимизации в карте - занеси в переменную Player(группа игроков) каждого игрока. Player[1] = группа игроков(Игрок 1) и т.д. И используй переменную
Бля ,да че вы мучаетесь ночью в полночь делаем random integer между 1 и 100 и если равен integer 10 -то это 1 % если 1.2.3.4.5.6.7.8.9.10 - то 10% шанс превращения остальные вообще ничего не делаем - я бы за пару часов такое сделал но да только вряд ли мне согласятся заплатить))
так там при каждом превращение определяется время суток и если день то шанс на превращение 10% а если ночь то 50% т.е в любое время ночи если клацнуть превращение в воргена медведя то есть шанс (ночью) в 50 процентов обезуметь стать волком. Днём же этот шанс меньше.
Хотя правда я ничего не понял из того что ты написал и не уверен триггерное ли ты мне предлагаешь . Вот взгляни если не трудно ... (мне осталось шанс сделать а я не понимаю как :с) да и просто посмотри может вообще не правильно это. static2.keep4u.ru/2015/09/23/PT.png
Я тебе говорю триггер который срабатывает когда наступает полночь - random integer 1-100 когда какая нибудь из 10 цифр выпадает превращайся в волка - другие в медведя или напиши мне в личку там подробнее обьясню
и вообще - зачем непосредственно превращаться в медведя способностью?
Не проще подменять персонажей во время превращения? Я так делал - так удобнее
вариант А - тупо добавить аним.таг юниту, его свойства не изменятся, просто будет выглядеть как медведь
вариант Б - делать абилки в спеллбуке пермаментными, тогда они не будут пропадать
Если заменить модель дерева на модель травы, с анимамцией пригинания при смерти. Убрать колизию, то может получится.
Вот примерная наработка на деревьях.
Честно я не знаю меняет родная защита и прочие характеристики юнита при использовании тёмный. Давно не игрался с этим. Да и делал я типа кур. Говорят там только модель меняется. А вот перевоплощение да там могут меняться атрибуты и прочее. Если так то редактируйте этого юнита. И вообще проверяйте сами все
При использовании абилы тёмный сам юнит никуда не удаляется, просто модель меняется (сам даже удалял много ещё) - трудно проверить?
А почему ты не можешь просто сделать так,чтобы предмет с твоей броней просто одевался на героя.Это самый простой вариант,в котором есть только одна проблема-найти/сделать модель этого предмета.
Работаю с ВоВ-моделью. Проще сделать много скинов к ней, как в самой ММО, чем модель брони.
Если заменить модель дерева на модель травы, с анимамцией пригинания при смерти. Убрать колизию, то может получится.
Вот примерная наработка на деревьях.
Честно я не знаю меняет родная защита и прочие характеристики юнита при использовании тёмный. Давно не игрался с этим. Да и делал я типа кур. Говорят там только модель меняется. А вот перевоплощение да там могут меняться атрибуты и прочее. Если так то редактируйте этого юнита. И вообще проверяйте сами все
При использовании абилы тёмный сам юнит никуда не удаляется, просто модель меняется (сам даже удалял много ещё) - трудно проверить?
А почему ты не можешь просто сделать так,чтобы предмет с твоей броней просто одевался на героя.Это самый простой вариант,в котором есть только одна проблема-найти/сделать модель этого предмета.
Работаю с ВоВ-моделью. Проще сделать много скинов к ней, как в самой ММО, чем модель брони.
Если имеется в виду очистить по первому ключу, то это FlushChildHashtable(hashtable, parentKey).
Если очистить по двум ключам, то можно просто записать в эту ячейку null.
По второму вопросу — конечно, можно, храни и загружай когда хочешь -_-
Для спеллов достаточно хештаблицы, массивы самое то для всяких систем перемещения, молний, очень часто повторяющихся операций с большими числом объектов....
Часто системы идут уже с собственным системами хранения данных, timer utils юзает свой атач на таймер или хештаблицу, ну и так далее.
» WarCraft 3 / Переключаемая способность
» Администрация XGM / Удаление аккаунта
» WarCraft 3 / Пассивный эффект?
» WarCraft 3 / UnitDamageTarget
» WarCraft 3 / Простой вопрос.
» WarCraft 3 / Как пользоваться мемхаком
» WarCraft 3 / тип ability
» WarCraft 3 / vJass
» WarCraft 3 / хештаблица
» WarCraft 3 / Утечка или нет?
» WarCraft 3 / Подъем
» WarCraft 3 / Таймер-массив
» WarCraft 3 / ИИ не добывает ресурсы
» WarCraft 3 / 3 анимации
» WarCraft 3 / Отключить ИИ крипам
» WarCraft 3 / Правильно я удаляю триггер?
» WarCraft 3 / Проходимость юнитов
» WarCraft 3 / Array Timer
» WarCraft 3 / События в JASS
» WarCraft 3 / Пустые строки
» WarCraft 3 / Превратиться в медведя
» WarCraft 3 / Проблема с моделью. Невидима поверхность в анимациях.
» WarCraft 3 / Замена Юнитов с помощью триггеров
» WarCraft 3 / Замена Юнитов с помощью триггеров
» WarCraft 3 / Hashtable